package it.uniroma3.dia.digraph;

import it.uniroma3.dia.digraph.algorithm.utility.Utility;
import it.uniroma3.dia.digraph.algorithm.utility.kouterplanar.outerplanar.OuterplanarNode;
import it.uniroma3.dia.digraph.algorithm.utility.stackedtri.StackedTriNode;
import it.uniroma3.dia.digraph.io.util.IoManager;
import it.uniroma3.dia.digraph.view.Finestrella;
import it.uniroma3.dia.digraph.view.View;

import java.awt.Point;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Point2D.Double;
import java.io.IOException;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;

import org.graphdrawing.graphml.xmlns.GraphType;
import org.graphdrawing.graphml.xmlns.GraphmlType;
import org.graphdrawing.graphml.xmlns.NodeCollectionType;
import org.graphdrawing.graphml.xmlns.NodeType;
import org.graphdrawing.graphml.xmlns.ObjectFactory;

public class Tester {
	
	public static void smain(String[] args) throws IOException{
		Point s, t, p;
		s = new Point();
		t = new Point();
		p = new Point();
		
		double SP, ST, TP;
		
		s.setLocation(0,4);
		t.setLocation(1,7);
		p.setLocation(8,28);
		
		SP = p.distance(s);
		ST = t.distance(s);
		TP = p.distance(t);
		
		double tc = SP/TP;
		double sc = - ST/TP;
		Point result = new Point();
		result.setLocation(s.getX()*sc + t.getX()*tc, s.getY()*sc + t.getY()*tc);
		System.out.println("sc: "+sc);
		System.out.println("st: "+tc);
		System.out.println("sum: "+(sc+tc));
		
		System.out.println(result);
		
	}
	
	public static void remain(String[] args) throws IOException{
		GraphmlType gml = new IoManager().loadFromFile("xml\\stackedTri.graphml");
		List<NodeType> hull = Utility.getNodesOnConvexHull(gml.getGraph().getNodeCollection().getNode());
		System.out.println("convex hull");
		for (NodeType n : hull){
			System.out.println(n.getId());
		}
		
		System.out.println("layers");
		for (Collection<StackedTriNode> ci : Utility.getDepthToNodes(gml.getGraph()).values())
			for (StackedTriNode n : ci)
				System.out.println(n.getId()+": "+n.getDepth());
		
	}
	
	public static void dmain(String[] args){
		ObjectFactory of = new ObjectFactory();
		NodeType p,a,b,c;
		p= of.createNodeType();a= of.createNodeType();b= of.createNodeType();c= of.createNodeType();
		a.setX(40); a.setY(560); b.setX(160); b.setY(400); c.setX(80); c.setY(40); p.setX(80); p.setY(440);
		double[] res = Utility.barycentricCoords(p, a, b, c);
		System.out.println((res[0]*a.getX())+" "+(res[1]*b.getX())+" "+(res[2]*c.getX()));
		
		
	}
	
	public static void main(String[] args){
		ObjectFactory of = new ObjectFactory();
		
		GraphType gr = of.createGraphType();
		NodeType p,c,n, x, center;
		Point2D.Double mid, centerPoint;
		NodeCollectionType nc = of.createNodeCollectionType();
		
		
		p = of.createNodeType();
		c = of.createNodeType();
		n = of.createNodeType();
		x = of.createNodeType();
		center = of.createNodeType();
		
		p.setX(600); p.setY(50); p.setId("prev");
		n.setX(650); n.setY(200); n.setId("next");
		c.setX(750); c.setY(200); c.setId("current");
		center.setId("center");
		
		mid = Utility.midpoint(p, n);
		double theta = calculateTheta(p, c, n);
		double[] coords;
		
		coords = Utility.convertToCartesianCoords(mid, theta, 150);
		x.setX(coords[0]);
		x.setY(coords[1]);
		x.setId("point");
		
//		centerPoint = Utility.getCircumCenter(p, new Point2D.Double(coords[0], coords[1]), center);
		centerPoint = Utility.getIsoscelesCircumCenter(mid, theta, p, new Point2D.Double(x.getX(), x.getY()));
		center.setX(centerPoint.getX());
		center.setY(centerPoint.getY());
		
		
		gr.setNodeCollection(nc);
		gr.setEdgeCollection(of.createEdgeCollectionType());
		
		gr.getNodeCollection().getNode().add(p);
		gr.getNodeCollection().getNode().add(c);
		gr.getNodeCollection().getNode().add(n);
		gr.getNodeCollection().getNode().add(x);
		gr.getNodeCollection().getNode().add(center);
		
		
		x.setDefault(false);
		
		
		
		View v = new View(gr);
		v.pack();
		v.setVisible(true);
		v.update(gr);
		
		System.out.println(Utility.distance(center, p));
		System.out.println(Utility.distance(center, n));
		System.out.println(Utility.distance(center, x));
		
		Finestrella.getChar();
		
		
		
		System.exit(0);
	}
	
	private static double calculateTheta(NodeType previous, NodeType current, NodeType next) {
		double theta, prevTheta, currTheta, nextTheta;
		
		Point2D.Double middle = Utility.midpoint(previous, next);
		
		
		prevTheta = Utility.getAngle(middle, previous);
		currTheta = Utility.getAngle(middle, current);
		nextTheta = Utility.getAngle(middle, next);

		if (nextTheta>=180){
			if (currTheta<nextTheta)
				theta = nextTheta + 90;
			else
				theta = nextTheta - 90;
		} else {
			if (currTheta< prevTheta)
				theta = prevTheta + 90;
			else
				theta = prevTheta - 90;
		}	
		
		
		theta = theta % 360;
		System.out.println(previous+" pt: "+prevTheta);
		System.out.println(current+" ct: "+currTheta);
		System.out.println(next+" nt: "+nextTheta);
		System.out.println("  th: "+theta);
		Finestrella.getChar();
		
		return theta;
	}
	

}

class Wrapper{
	public int value;
}

class WrapperComp implements Comparator<Wrapper>{

	@Override
	public int compare(Wrapper o1, Wrapper o2) {
		
		return o2.value-o1.value;
	}
	
}
